/*
 * SoundControl.c
 *
 *  Created on: 27.09.2011
 *      Author: windows97
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include "Globals.h"
#include "TimerControl.h"
#include "HwAbstraction.h"
#include "SoundControl.h"

#define BEEP_FREQUENCY          1900
#define BEEP_PRELOAD            (uint8_t)(255-(F_CPU/64/BEEP_FREQUENCY/2))
#define SCO_NO_OF_BEEPMODES_U8   ((uint8_t)(5U))

static uint8_t gSoundHeartbeat_u8 = 0;

void ScoHeartbeat(void);

typedef struct _T_BeepMode
{
  uint8_t BeepOn_u8;
  uint8_t BeepReload_u8;
} T_BeepMode;

const T_BeepMode cBeepModes_u8a[SCO_NO_OF_BEEPMODES_U8] = {{.BeepOn_u8 = 24, .BeepReload_u8 = 25}, \
                                      {.BeepOn_u8 = 49, .BeepReload_u8 = 50}, \
                                      {.BeepOn_u8 = 18, .BeepReload_u8 = 20}, \
                                      {.BeepOn_u8 = 15, .BeepReload_u8 = 16}, \
                                      {.BeepOn_u8 = 199, .BeepReload_u8 = 200} };

static uint8_t gBeepMode_u8 = SCO_NO_OF_BEEPMODES_U8-1;
static T_SoundOnOff gSoundOn_u8 = SoundOff;

ISR(TIMER2_OVF_vect)
{
  TOG_SOUND_OUT_PIN;
  TCNT2 = BEEP_PRELOAD;
}

void ScoInit( void )
{
  TIMSK2 |= (1 << TOIE2); //Compare match
  TCNT2 = 0;
  TicRegisterNotification( ScoHeartbeat );
}

void ScoSetSound( T_SoundOnOff iOnOff_t )
{
  if( ( SoundOff == gSoundOn_u8 ) &&
      ( SoundOn  == iOnOff_t ) )
  {
    gSoundOn_u8 = SoundOn;
  }
  else if( ( SoundOn == gSoundOn_u8 ) &&
           ( SoundOff  == iOnOff_t ) )
  {
    /* switch of port */
    gSoundOn_u8 = SoundOff;
  }
}

void ScoSetBeepLength( uint8_t iBeepLength_u8 )
{
  if( SCO_NO_OF_BEEPMODES_U8 <= iBeepLength_u8 )
  {
    gBeepMode_u8 = iBeepLength_u8;
  }
}

uint8_t ScoGetBeepMode( void )
{
   uint8_t lBeepMode_u8 = 0xFF;
  if( SoundOn == gSoundOn_u8 )
  {
     lBeepMode_u8 = gBeepMode_u8;
  }
  return (lBeepMode_u8);
}

void ScoDecBeepMode( void )
{
  if( 0 < gBeepMode_u8 )
  {
    --gBeepMode_u8;
  }
}

void ScoHeartbeat( void )
{
  ++gSoundHeartbeat_u8;
}

void ScoCyclic( void )
{
  if(( gSoundHeartbeat_u8 >= cBeepModes_u8a[gBeepMode_u8].BeepOn_u8 ) &&
     ( SoundOn == gSoundOn_u8          ) )
  {
    TCCR2B = ((1<<CS01) | (1<<CS00));
  }

  if ( gSoundHeartbeat_u8 >= cBeepModes_u8a[gBeepMode_u8].BeepReload_u8 )
  { /* One second passed */
    /* disable timer */
    TCCR2B = 0;
    /* switch of port */
    CLR_SOUND_OUT_PIN; /* Clear the pin explicitly */
    gSoundHeartbeat_u8 = 0;
  }
}
